import gugga.collections.CheckList;
import gugga.collections.ArrayList;

import test_framework.test.unit.TestCase;

/**
 * @author vladimir
 */
class guggaLibTests.CheckListTest
		extends TestCase
{
	public function CheckListTest()
	{
		super();
	}
	
	public function testConstructor()
	{
		var checkList:CheckList = new CheckList();
		assertNotNull(
				"checkList should not be null after creation", 
				checkList);
		assertNotUndefined(
				"checkList should not be undefined after creation", 
				checkList);
		
		var registeredObjects:ArrayList = checkList.RegisteredObjects;
		assertNotNull(
				"registeredObjects ArrayList should not be null after creation", 
				registeredObjects);
		assertNotUndefined(
				"registeredObjects ArrayList should not be undefined after creation", 
				registeredObjects);
		assertTrue(
				"registeredObjects ArrayList should be empty right after creation",
				registeredObjects.isEmpty());
		
		var checkedObjects:ArrayList = checkList.CheckedObjects;
		assertNotNull(
				"checkedObjects ArrayList should not be null after creation", 
				checkedObjects);
		assertNotUndefined(
				"checkedObjects ArrayList should not be undefined after creation", 
				checkedObjects);
		assertTrue(
				"checkedObjects ArrayList should be empty right after creation",
				checkedObjects.isEmpty());
		
		var uncheckedObjects:ArrayList = checkList.UncheckedObjects;
		assertNotNull(
				"uncheckedObjects ArrayList should not be null after creation", 
				uncheckedObjects);
		assertNotUndefined(
				"uncheckedObjects ArrayList should not be undefined after creation", 
				uncheckedObjects);
		assertTrue(
				"uncheckedObjects ArrayList should be empty right after creation",
				uncheckedObjects.isEmpty());
	}
	
	public function testAdd()
	{
		var checkList:CheckList = new CheckList();
		
		var object1:Object = new Object();
		checkList.add(object1);
		
		var registeredObjects:ArrayList = checkList.RegisteredObjects;
		assertFalse(
				"registeredObjects ArrayList should not be empty right after adding object1 to the checkList",
				registeredObjects.isEmpty());
		assertTrue(
				"object1 should be registered after adding it to the checkList", 
				checkList.isObjectRegistered(object1));
		assertEquals(
				"registeredObjects ArrayList should contain 1 object after adding object1 to the checkList",
				registeredObjects.length, 
				1);
		assertTrue(
				"registeredObjects ArrayList should contain object1 after adding object1 to the checkList(nothing has been checked yet)",
				registeredObjects.containsItem(object1));
		
		var uncheckedObjects:ArrayList = checkList.UncheckedObjects;
		assertEquals(
				"uncheckedObjects ArrayList should contain 1 object after adding object1 to the checkList(nothing has been checked yet)",
				uncheckedObjects.length, 
				1);
		assertTrue(
				"uncheckedObjects ArrayList should contain object1 after adding object1 to the checkList(nothing has been checked yet)",
				uncheckedObjects.containsItem(object1));
		
		var checkedObjects:ArrayList = checkList.CheckedObjects;
		assertTrue(
				"checkedObjects ArrayList should be empty after adding object1 to the checkList(nothing has been checked yet)",
				checkedObjects.isEmpty());
		assertFalse(
				"checkList.isObjectChecked(object1) should be false(nothing has been checked yet)",
				checkList.isObjectChecked(object1));
		
		var object2:Object = new Object();
		checkList.add(object2);
		
		registeredObjects = checkList.RegisteredObjects;
		assertFalse(
				"registeredObjects ArrayList should not be empty right after adding object1 and object2 to the checkList",
				registeredObjects.isEmpty());
		assertTrue(
				"object2 should be registered after adding it to the checkList", 
				checkList.isObjectRegistered(object2));
		assertEquals(
				"registeredObjects ArrayList should contain 2 objects after adding object1 and object2 to the checkList",
				registeredObjects.length, 
				2);
		assertTrue(
				"registeredObjects ArrayList should contain object1 and object2 after adding object1 and object2 to the checkList(nothing has been checked yet)",
				registeredObjects.containsItem(object1) && registeredObjects.containsItem(object2));
		
		uncheckedObjects = checkList.UncheckedObjects;
		assertEquals(
				"uncheckedObjects ArrayList should contain 2 objects after adding object1 and object2 to the checkList(nothing has been checked yet)",
				uncheckedObjects.length, 
				2);
		assertTrue(
				"uncheckedObjects ArrayList should contain object1 and object2 after adding object1 and object2 to the checkList(nothing has been checked yet)",
				uncheckedObjects.containsItem(object1) && uncheckedObjects.containsItem(object2));
		
		checkedObjects = checkList.CheckedObjects;
		assertTrue(
				"checkedObjects ArrayList should be empty after adding object1 and object2 to the checkList(nothing has been checked yet)",
				checkedObjects.isEmpty());
		assertFalse(
				"checkList.isObjectChecked(object1) && checkList.isObjectChecked(object2) should be false(nothing has been checked yet)",
				checkList.isObjectChecked(object1) && checkList.isObjectChecked(object2));
	}
	
	public function testRemove()
	{
		var checkList:CheckList = new CheckList();
		
		var object1:Object = new Object();
		checkList.add(object1);
		
		var object2:Object = new Object();
		checkList.add(object2);
		
		// in order to test checkedObjects ArrayList after remove, I need to 
		// check object2 in the checkList(after checking this object the 
		// checkedObjects ArrayList will contain one object - after removing 
		// this  object, checkedObjects ArrayList should be empty):
		checkList.check(object2);
		
		checkList.remove(object2);
		var registeredObjects:ArrayList = checkList.RegisteredObjects;
		assertFalse(
				"registeredObjects ArrayList should not be empty after removing object2(object1 is still in the checkList)",
				registeredObjects.isEmpty());
		assertEquals(
				"registeredObjects ArrayList should contain 1 object after removing object2 from the checkList(object1 is still in the checkList)",
				registeredObjects.length, 
				1);
		assertTrue(
				"registeredObjects ArrayList should contain object1 after removing object2 from the checkList(object1 is still in the checkList)",
				registeredObjects.containsItem(object1));
		assertFalse(
				"object2 should not be registered after removing it from the checkList", 
				checkList.isObjectRegistered(object2));
		assertTrue(
				"object1 should be registered after removing object2 from the checkList(object1 is still in the checkList)", 
				checkList.isObjectRegistered(object1));
		
		var checkedObjects:ArrayList = checkList.CheckedObjects;
		assertTrue(
				"checkedObjects ArrayList should be empty after removing object2 from the checkList(nothing else has been checked yet)",
				checkedObjects.isEmpty());
		assertFalse(
				"checkList.isObjectChecked(object2) should be false(object2 has been removed from the checkList)",
				checkList.isObjectChecked(object2));
		
		var uncheckedObjects:ArrayList = checkList.UncheckedObjects;
		assertEquals(
				"uncheckedObjects ArrayList should contain 1 object after adding object1 to the checkList(nothing has been checked yet)",
				uncheckedObjects.length, 
				1);
		assertTrue(
				"uncheckedObjects ArrayList should still contain object1 after removing object2 from the checkList(object1 has not been checked yet)",
				uncheckedObjects.containsItem(object1));
		
		checkList.remove(object1);
		registeredObjects = checkList.RegisteredObjects;
		assertTrue(
				"registeredObjects ArrayList should now be empty after removing object2 and object1(checkList is empty)",
				registeredObjects.isEmpty());
		assertFalse(
				"object1 should not be registered after removing it from the checkList", 
				checkList.isObjectRegistered(object1));
		
		uncheckedObjects = checkList.UncheckedObjects;
		assertTrue(
				"uncheckedObjects ArrayList should now be empty after removing object2 and object1(checkList is empty)",
				uncheckedObjects.isEmpty());
	}
	
	public function testReset()
	{
		var checkList:CheckList = new CheckList();
		
		var object1:Object = new Object();
		checkList.add(object1);
		
		var object2:Object = new Object();
		checkList.add(object2);
		
		checkList.check(object2);
		var checkedObjects:ArrayList = checkList.CheckedObjects;
		assertFalse(
				"checkedObjects ArrayList should not be empty after checking object2",
				checkedObjects.isEmpty());
		assertEquals(
				"checkedObjects ArrayList should contain 1 object after checking object2",
				checkedObjects.length, 
				1);
		assertTrue(
				"checkedObjects ArrayList should contain object2 after checking object2",
				checkedObjects.containsItem(object2));
		assertTrue(
				"checkList.isObjectChecked(object2) should be true after checking object2", 
				checkList.isObjectChecked(object2));
		
		var uncheckedObjects:ArrayList = checkList.UncheckedObjects;
		assertFalse(
				"uncheckedObjects ArrayList should not be empty after checking object2(object1 is not checked yet)",
				uncheckedObjects.isEmpty());
		assertEquals(
				"uncheckedObjects ArrayList should contain 1 object after checking object2(object1 is not checked yet)",
				uncheckedObjects.length, 
				1);
		assertTrue(
				"uncheckedObjects ArrayList should contain object1(object1 is not checked yet)",
				uncheckedObjects.containsItem(object1));
		assertFalse(
				"checkList.isObjectChecked(object1) should be false(object1 is not checked yet)", 
				checkList.isObjectChecked(object1));
		
		var registeredObjectsBeforeReset:ArrayList = checkList.RegisteredObjects;
		
		checkList.reset();
		checkedObjects = checkList.CheckedObjects;
		assertTrue(
				"checkedObjects ArrayList should be empty after reset",
				checkedObjects.isEmpty());
		assertFalse(
				"checkList.isObjectChecked(object2) should be false after reset", 
				checkList.isObjectChecked(object2));
		
		uncheckedObjects = checkList.UncheckedObjects;
		assertFalse(
				"uncheckedObjects ArrayList should not be empty after reset(everything is unchecked)",
				uncheckedObjects.isEmpty());
		assertEquals(
				"uncheckedObjects ArrayList should contain 2 object after reset(everything is unchecked)",
				uncheckedObjects.length, 
				2);
		assertTrue(
				"uncheckedObjects ArrayList should contain object1 and object2(everything is unchecked)",
				uncheckedObjects.containsItem(object1) && uncheckedObjects.containsItem(object2));
		assertFalse(
				"checkList.isObjectChecked(object1) && checkList.isObjectChecked(object2) should be false(everything is unchecked)", 
				checkList.isObjectChecked(object1) && checkList.isObjectChecked(object2));
		
		var registeredObjectsAfterReset:ArrayList = checkList.RegisteredObjects;
		
		// registered objects should be the same after reset:
		for(var i:Number = 0; i < registeredObjectsBeforeReset.length; i++)
		{
			assertEquals(
				"registeredObjectsBeforeReset[" + i + "] should equals to registeredObjectsAfterReset[" + i + "]",
				registeredObjectsBeforeReset[i],
				registeredObjectsAfterReset[i]);
		}
	}
	
	public function testCheck()
	{
		var checkList:CheckList = new CheckList();
		
		var object1:Object = new Object();
		checkList.add(object1);
		
		var object2:Object = new Object();
		checkList.add(object2);
		
		checkList.check(object1);
		var checkedObjects:ArrayList = checkList.CheckedObjects;
		assertFalse(
				"checkedObjects ArrayList should not be empty after checking object1",
				checkedObjects.isEmpty());
		assertEquals(
				"checkedObjects ArrayList should contain 1 object after checking object1",
				checkedObjects.length, 
				1);
		assertTrue(
				"checkedObjects ArrayList should contain object1 after checking object1",
				checkedObjects.containsItem(object1));
		assertTrue(
				"checkList.isObjectChecked(object1) should be true after checking object1", 
				checkList.isObjectChecked(object1));
		
		var uncheckedObjects:ArrayList = checkList.UncheckedObjects;
		assertFalse(
				"uncheckedObjects ArrayList should not be empty after checking object1(object2 is not checked yet)",
				uncheckedObjects.isEmpty());
		assertEquals(
				"uncheckedObjects ArrayList should contain 1 object after checking object1(object2 is not checked yet)",
				uncheckedObjects.length, 
				1);
		assertTrue(
				"uncheckedObjects ArrayList should contain object2(object2 is not checked yet)",
				uncheckedObjects.containsItem(object2));
		assertFalse(
				"checkList.isObjectChecked(object2) should be false(object2 is not checked yet)", 
				checkList.isObjectChecked(object2));
		
		checkList.check(object2);
		
		checkedObjects = checkList.CheckedObjects;
		assertFalse(
				"checkedObjects ArrayList should not be empty after checking object2(it also contains object1)",
				checkedObjects.isEmpty());
		assertEquals(
				"checkedObjects ArrayList should contain 2 object after checking object2(it also contains object1)",
				checkedObjects.length, 
				2);
		assertTrue(
				"checkedObjects ArrayList should contain object1 and object2 after checking object2",
				checkedObjects.containsItem(object1) && checkedObjects.containsItem(object2));
		assertTrue(
				"checkList.isObjectChecked(object1) && checkList.isObjectChecked(object2) should be true after checking object2(object1 is also checked)", 
				checkList.isObjectChecked(object1) && checkList.isObjectChecked(object2));
		
		uncheckedObjects = checkList.UncheckedObjects;
		assertTrue(
				"uncheckedObjects ArrayList should be empty after checking object2(object1 is also checked)",
				uncheckedObjects.isEmpty());
	}
	
	public function testIsCompleted()
	{
		var checkList:CheckList = new CheckList();
		
		assertTrue(
				"checkList.isCompleted() should be true(checkList is empty after creation)",
				checkList.isCompleted());
		
		var object1:Object = new Object();
		checkList.add(object1);
		
		var object2:Object = new Object();
		checkList.add(object2);
		
		assertFalse(
				"checkList.isCompleted() should be false(still has two unchecked objects)",
				checkList.isCompleted());
		
		checkList.check(object2);
		assertFalse(
				"checkList.isCompleted() should be false(still object1 is unchecked, though object2 is checked)",
				checkList.isCompleted());
		
		checkList.check(object1);
		assertTrue(
				"checkList.isCompleted() should be true(all objects were checked)",
				checkList.isCompleted());
	}
}